/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/

package com.cea.papyrus.diagram.statemachine;


import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartFactory;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.ConnectionPointReference;
import org.eclipse.uml2.uml.Constraint;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.FinalState;
import org.eclipse.uml2.uml.Pseudostate;
import org.eclipse.uml2.uml.Region;

import com.cea.papyrus.core.editor.EditpartFactoryBase;
import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.editpart.AnchorEditPart;
import com.cea.papyrus.core.editpart.GraphEdgeEditPart;
import com.cea.papyrus.core.editpart.GraphNodeWithSemanticEditPart;
import com.cea.papyrus.diagram.classdiagram.editpart.CommentEditPart;
import com.cea.papyrus.diagram.classdiagram.editpart.ConstraintEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.ConnectionPointReferenceEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.FinalStateEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.NodeNameDisplayEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.PseudostateEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.RegionEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.StateEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.StateMachineDiagramEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.StateMachineEditPart;
import com.cea.papyrus.diagram.statemachine.editpart.TransitionEditPart;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;

/**
 * Manages creation of controller for state machine diagram elements.
 * 
 * @author David Servat
 * @since 29 jan. 07
 */

public class StateMachineGraphicalEditPartsFactory extends EditpartFactoryBase implements EditPartFactory
{

	/**
	 * The channel.
	 */
	private int channel = 501;

	/**
	 * The model manager.
	 */
	protected ModelManager modelManager;

	/**
	 * The Constructor.
	 * 
	 * @param modelManager the model manager
	 */
	public StateMachineGraphicalEditPartsFactory(ModelManager modelManager){
		this.modelManager = modelManager;
	}

	/**
	 * Creates the edit part.
	 * 
	 * @param obj the obj
	 * @param context the context
	 * 
	 * @return the edit part
	 */
	public EditPart createEditPart(EditPart context, Object obj){
		//new mechanism
		EditPart result= getEditPartFromProperty(context, obj,modelManager);
		if (result!=null){
			return result;
		}
		
		//to identify the good editpart we need 
		//the nature of the object (graphEdge or graphNode) 
		//and the uml Element connected

		// Case of a diagram
		if(obj instanceof Diagram)
			return new StateMachineDiagramEditPart((Diagram)obj,modelManager);
		else if(obj instanceof GraphNode){
			//dealing with creation of edit part for labels
			if (((GraphNode) obj).getSemanticParent() != null){
				Element elt = ((Uml1SemanticModelBridge)((GraphElement)((GraphNode) obj).getSemanticParent()).getSemanticModel()).getElement();
				if((elt instanceof Pseudostate) || (elt instanceof FinalState) || (elt instanceof Region) || (elt instanceof ConnectionPointReference)){
					Element umlSemanticParent= ((Uml1SemanticModelBridge)((GraphElement)((GraphNode) obj).getSemanticParent()).getSemanticModel()).getElement();
					((GraphNode) obj).setSemanticModel(null);
					return new NodeNameDisplayEditPart((GraphNode) obj, umlSemanticParent, modelManager);
				}
			}
			if(((Uml1SemanticModelBridge)((GraphNode)obj).getSemanticModel()) == null)
				return new AnchorEditPart((GraphNode)obj,modelManager);
			if((((Uml1SemanticModelBridge)((GraphNode)obj).getSemanticModel()).getElement()) == null)
				return new GraphNodeWithSemanticEditPart((GraphNode)obj,modelManager);
			Element elt = ((Uml1SemanticModelBridge)((GraphNode)obj).getSemanticModel()).getElement();
			return searchEditPart((GraphNode)obj, elt);
		}

		//Case of a graph edge
		else if(obj instanceof GraphEdge){
			if(((Uml1SemanticModelBridge)((GraphEdge)obj).getSemanticModel()) != null){
				Element elt = ((Uml1SemanticModelBridge)((GraphEdge)obj).getSemanticModel()).getElement();
				return searchEditPart((GraphEdge)obj, elt);		
			}
			else{
				GraphEdge ge=(GraphEdge)obj;
				return new GraphEdgeEditPart(ge,modelManager);		
			}
		}

		return null;
	}

	/**
	 * Create the good Edit part from the the GraphNode and the Element.
	 * 
	 * @param graphNode the graph node
	 * @param elt the elt
	 * 
	 * @return the edit part
	 */
	public EditPart searchEditPart(GraphNode graphNode, Element elt){

		//Constraint
		if(elt instanceof Constraint)
			return new ConstraintEditPart(graphNode, modelManager);

		//Comment
		if(elt instanceof Comment)
			return new CommentEditPart(graphNode, modelManager);

//		//ConnectionPointReference
		if(elt instanceof org.eclipse.uml2.uml.ConnectionPointReference)
			return new ConnectionPointReferenceEditPart(graphNode, modelManager);

		//FinalState
		if(elt instanceof org.eclipse.uml2.uml.FinalState)
			return new FinalStateEditPart(graphNode, modelManager);

//		//ProtocolStateMachine
//		if(elt instanceof org.eclipse.uml2.uml.ProtocolStateMachine)
//			return new StateMachineEditPart(graphNode, modelManager);

		//Pseudostate
		if(elt instanceof org.eclipse.uml2.uml.Pseudostate)
			return new PseudostateEditPart(graphNode, modelManager);

		//Region
		if(elt instanceof org.eclipse.uml2.uml.Region)
			return new RegionEditPart(graphNode, modelManager);

		//State
		if(elt instanceof org.eclipse.uml2.uml.State)
			return new StateEditPart(graphNode, modelManager);

		//StateMachine
		if(elt instanceof org.eclipse.uml2.uml.StateMachine)
			return new StateMachineEditPart(graphNode, modelManager);

		return null;
	}

	/**
	 * Create the good Edit part from the the GraphEdge and the Element.
	 * 
	 * @param graphEdge the graph edge
	 * @param elt the elt
	 * 
	 * @return the edit part
	 */
	public EditPart searchEditPart(GraphEdge graphEdge, Element elt){

		// Comment / Constraint Link
		if(elt instanceof com.cea.papyrus.core.pseudoelement.GraphicalLink)
			return new GraphEdgeEditPart(graphEdge, modelManager);
		
		//Transition
		if(elt instanceof org.eclipse.uml2.uml.Transition){
			return new TransitionEditPart(graphEdge, modelManager);}

//		//ProtocolConformance
//		if(elt instanceof org.eclipse.uml2.uml.ProtocolConformance){
//			return new GraphEdgeEditPart(graphEdge, modelManager);}
//
//		//ProtocolTransition
//		if(elt instanceof org.eclipse.uml2.uml.ProtocolTransition){
//			return new GraphEdgeEditPart(graphEdge, modelManager);}
//

	

		return null;
	}

}
